module csrs_mod(
	rst,

	//id读取模块
	csr_addr_i,
	csr_data_o,
	csr_mtvec_o,
	csr_mepc_o,
	csr_mie_o,
	csr_mip_o,
	csr_mstatus_o,

	//csr状态寄存器处理接口
	csr_en_i,
	csr_addr1_i,
	csr_data_i,

	//中断实现接口
	csr_int_en_i,
	csr_mepc_i,
	csr_mcause_i,
	csr_mtval_i,
	csr_mstatus_i,

	//中断
	timer_int,
	external_int
);

input rst;
//id读取模块
input [11:0] csr_addr_i;

output reg [31:0] csr_data_o;
output reg [31:0] csr_mtvec_o;
output reg [31:0] csr_mepc_o;
output reg [31:0] csr_mie_o;
output reg [31:0] csr_mip_o;
output reg [31:0] csr_mstatus_o;

//csr状态寄存器处理接口
input csr_en_i;
input [11:0] csr_addr1_i;
input [31:0] csr_data_i;

//中断实现接口
input csr_int_en_i;
input [31:0] csr_mepc_i;
input [31:0] csr_mcause_i;
input [31:0] csr_mtval_i;
input [31:0] csr_mstatus_i;

input timer_int;
input external_int;
//0 0x300 mstatus
//1 0x304 mie
//2 0x305 mtvec
//3 0x340 mscratch
//4 0x341 mepc
//5 0x342 mcause
//6 0x343 mtval
//7 0x344 mip

reg [31:0] csr[7:0];

always @( csr_addr_i or csr_data_o or csr_mtvec_o or csr_mepc_o or csr_mie_o or csr_mip_o or csr_mstatus_o or rst) begin
	if (rst) begin
		// reset
		csr_data_o <= 32'h0;
		csr_mtvec_o <= 32'h0;
		csr_mie_o <= 32'h0;
		csr_mip_o <= 32'h0;
		csr_mstatus_o <= 32'h0;
	end else begin
		case ( csr_addr_i )
			12'h300 : csr_data_o <= csr[0];
			12'h304 : csr_data_o <= csr[1];
			12'h305 : csr_data_o <= csr[2];
			12'h340 : csr_data_o <= csr[3];
			12'h341 : csr_data_o <= csr[4];
			12'h342 : csr_data_o <= csr[5];
			12'h343 : csr_data_o <= csr[6];
			12'h344 : csr_data_o <= csr[7];
		endcase
		csr_mtvec_o <= csr[2];
		csr_mepc_o <= csr[4];
		csr_mie_o <= csr[1];
		csr_mip_o <= csr[7];
		csr_mstatus_o <= csr[0];
	end
end

always @(csr_en_i or csr_addr_i or csr_data_i or csr_int_en_i or csr_mepc_i or csr_mcause_i or csr_mtval_i or csr_mstatus_i or rst) begin
	if (rst) begin
		// reset
		csr[0] <= 32'b0;
		csr[1] <= 32'b0;
		csr[2] <= 32'b0;
		csr[3] <= 32'b0;
		csr[4] <= 32'b0;
		csr[5] <= 32'b0;
		csr[6] <= 32'b0;
		csr[7] <= 32'b0;
	end else if ( csr_int_en_i == 1'b1 ) begin
		csr[4] <= csr_mepc_i;
		csr[5] <= csr_mcause_i;
		csr[6] <= csr_mtval_i;
		csr[0] <= csr_mstatus_i;
	end else if ( csr_en_i == 1'b1 ) begin
		case ( csr_addr1_i )
			12'h300 : csr[0] <= csr_data_i;
			12'h304 : csr[1] <= csr_data_i;
			12'h305 : csr[2] <= csr_data_i;
			12'h340 : csr[3] <= csr_data_i;
			12'h341 : csr[4] <= csr_data_i;
			12'h342 : csr[5] <= csr_data_i;
			12'h343 : csr[6] <= csr_data_i;
			12'h344 : csr[7] <= csr_data_i;
		endcase
	end else begin
		if( csr[0][3] == 1'b1 ) begin
			if ( timer_int == 1'b1) begin
				csr[7] <= csr[7] | 32'b10000000;
			end 
			if ( external_int == 1'b1 )begin
				csr[7] <= csr[7] | 32'b100000000000;
			end
		end
	end
end

endmodule
